/**
 * 
 */
package cn.edu.cqu.bysj.wm.ago.gn;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;

import cn.edu.cqu.bysj.wm.def.ConstDef;
import cn.edu.cqu.bysj.wm.neo4j.Neo4jTraversal;

/**
 * @author Meng
 * 
 *         Define and Implement Useful Judge Method for GN Algorithm
 */
public class JudgeRule {

	public static Set<Node> componentNodes;
	public static Set<Relationship> componentRels;

	public static List<Node> snList;
	public static List<Relationship> srList;
	public static List<Node> enList;
	public static List<Relationship> erList;

	/**
	 * judge n-1 rule
	 * 
	 * @param max
	 *            betweenness value
	 * @param n
	 *            nodes number
	 * @return 1 or 0
	 */
	public static int judgeNSub1Rule(int max, long n) {
		return max < n - 1 ? 0 : 1;
	}

	/**
	 * judge partition
	 * 
	 * @param sNode
	 * @param eNode
	 * @param gdb
	 * @param hTree
	 * @return status
	 */
	public static int judgePartition(Node sNode, Node eNode,
			GraphDatabaseService gdb, HierarchyTree hTree) {

		// gain node list of the start node and end node
		snList = Neo4jTraversal.connectGraphNodes(sNode);
		enList = Neo4jTraversal.connectGraphNodes(eNode);

		// gain relationship list of the start node and end node
		srList = Neo4jTraversal.connectGraphEdges(sNode);
		erList = Neo4jTraversal.connectGraphEdges(eNode);

		// have intersection or not?
		if (Collections.disjoint(snList, enList)) {

			// judge minimum component rule
			if (judgeThree(snList, enList)) {
				GNCommunity.fillHierarchyTree(snList, gdb, hTree);
				GNCommunity.fillHierarchyTree(enList, gdb, hTree);
				return ConstDef.PARTITION_OK;
			}
			return ConstDef.LESS_THAN_TTREE;
		}

		// gain the component of node and relationship
		componentNodes = new HashSet<Node>(snList);
		componentNodes.addAll(enList);
		componentRels = new HashSet<Relationship>(srList);
		componentRels.addAll(erList);

		return ConstDef.ONLY_DELETE_EDGE;
	}

	/**
	 * judge min component rule
	 * 
	 * @param list1
	 * @param list2
	 * @return true or false
	 */
	private static boolean judgeThree(List<Node> list1, List<Node> list2) {

		if (list1.size() < ConstDef.MIN_COMMUNITY_SIZE
				|| list2.size() < ConstDef.MIN_COMMUNITY_SIZE) {
			return false;
		}
		return true;
	}
}
